// Observer/Subscriber  : 观察者
// Observable/ Publisher : 发布者
// Topic / EventType ：话题

export type EventHandler = (...args: any[]) => void;
// 虽然这两个类型简单，但是可能以后会增加 tableName 或者 EvenType 的类型
export type TableName = string
export type EventType = string

export class Emiter<TName extends TableName = TableName, EType extends EventType = EventType>{
  private static inst: Emiter
  private topics: Map<TName, Map<EType, EventHandler>> = new Map()

  static getInstance() {
    if (!Emiter.inst) {
      this.inst = new Emiter()
    }

    return this.inst
  }

  /**
   * @vuese 获取话题
   * @param type 
   */
  public getTopic(tableName: TName, evenType: EType): EventHandler{
    return this.topics.get(tableName).get(evenType)
  }

  /**
   * @vuese 注销
   * @param type 
   * @param handler 
   */
  public removeTable(tableName: TName) {
    if (!this.topics.has(tableName)) {
      return
    }

    this.topics.delete(tableName)
  }

  // 监听
  on(tableName:TName,evenType: EType, handler: EventHandler) {
    let table = this.topics.get(tableName)

    !table &&  this.topics.set(tableName,(table =  new Map()))

    table.set(evenType, handler)

    // 返回事件的卸载
    return () => {
      this.removeTable(tableName)
    }
  }

  // 触发
  emit<T = any>(tableName: TName, evenType: EType, ...args: any[]):T {
    const handler = this.getTopic(tableName, evenType)
    
    try {
      return handler(...args) as T
    } catch (e) {
      console.log(e) 
    }
  }
}